package cn.jtfadmin.base.lang.common.service;


import cn.jtfadmin.base.lang.common.domain.dto.*;
import cn.jtfadmin.base.lang.common.domain.entity.IdEntity;
import org.springframework.lang.Nullable;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;

/**
 * 基础服务类
 *
 * @param <T> 实体类型
 */
@Valid
public interface BaseService<T extends IdEntity> {


    /****************** 按照id查询 实体 *****************************/
    /**
     * 按照id查询
     *
     * @param id id
     * @return 数据
     */
    Optional<T> findById(@NotNull String id);

    /**
     * 按照id查询
     *
     * @param ids id,id,...
     * @return 数据
     */
    List<T> findByIds(@NotBlank String ids);

    /**
     * 按照id查询
     *
     * @param ids ids
     * @return 数据
     */
    List<T> findByIds(@NotNull Collection<String> ids);



    /**
     * 按照id查询实体
     *
     * @param id
     * @return 实体
     * @throws NoSuchElementException 当数据没有找到时抛出
     */
    T findRequiredById(@NotNull String id) throws NoSuchElementException ;


    /****************** 按照id查询 模型 *****************************/
    /**
     * 按照id查询
     *
     * @param id id
     * @param modelClass modelClass
     * @return 数据
     */
    <V> Optional<V> findModelById(@NotNull String id, @NotNull Class<V> modelClass);

    /**
     * 按照id查询
     *
     * @param ids id,id,...
     * @param modelClass modelClass
     * @return 数据
     */
    <V> List<V> findModelByIds(@NotBlank String ids,  @NotNull Class<V> modelClass);

    /**
     * 按照id查询
     *
     * @param ids ids
     * @param modelClass modelClass
     * @return 数据
     */
    <V> List<V>  findModelByIds(@NotNull List<String> ids, @NotNull Class<V> modelClass);

    /**
     * 按照id查询实体
     *
     * @param id
     * @param modelClass modelClass
     * @return 实体
     * @throws NoSuchElementException 当数据没有找到时抛出
     */
    <V>  V findModelRequiredById(@NotNull String id, @NotNull Class<V> modelClass) throws NoSuchElementException ;

    /****************** 按照字段查询 模型 *****************************/

    /**
     * 按照字段获取一个
     * @param fieldName 字段名
     * @param value 字段值
     * @return
     */
    Optional<T> findOneByField(@NotBlank String fieldName, Object value);


    /**
     * 按照字段查询-
     * @param fieldName 字段名
     * @param value 字段值
     * @return
     */
    T findRequiredOneByField(@NotBlank String fieldName, Object value);

    /****************** 按照查询条件查询  *****************************/
    /**
     * 按照字段查询
     * @param fieldName 字段名
     * @param value 字段值
     * @return
     */
    List<T> findByField(@NotBlank String fieldName, Object value);


    /**
     * 查询所有
     *
     * @param specPDTO 查询条件和排序条件
     * @return
     */
    List<T> findAll(@Nullable SpecPDTO<T> specPDTO);


    /**
     * 查询参数
     * @param specConditions
     * @return
     */
    List<T> findAll(@Nullable List<SpecConditionDTO> specConditions);


    /**
     * 查询所有
     * @param specConditions 查询条件
     * @param orderColumn 排序列
     * @param order 排序 desc/asc
     * @return
     */
    List<T> findAll(@Nullable List<SpecConditionDTO> specConditions, @NotBlank String orderColumn, @NotBlank String order);

    /**
     * 分页查询
     *
     * @param specPagePDTO 条件和分页
     * @return
     */
    PageRDTO<T> findAll(@NotNull SpecPagePDTO<T> specPagePDTO);


    /****************** 按照查询条件查询  模型 *****************************/

    /**
     * 按照查询条件查询
     * @param specPDTO 查询条件
     * @param modelClass modelClass
     * @param <V> modelClass
     * @return
     */
    <V> List<V>  findModelAll(@Nullable SpecPDTO<T> specPDTO, @NotNull Class<V> modelClass);




    /**
     * 按照查询条件查询
     * @param specPDTO 查询条件
     * @param modelClass modelClass
     * @param <V> modelClass
     * @return
     */
    <V> PageRDTO<V>  findModelAll(@Nullable SpecPagePDTO<T> specPDTO, @NotNull Class<V> modelClass);


    /****************** 按照查询条件查询  删除 *****************************/
    /**
     * 按照id删除
     *
     * @param id id
     */
    void deleteById(@NotBlank String id);

    /**
     * 按照id 批量删除
     *
     * @param ids id,id,...
     */
    void deleteBatch(@NotBlank String ids);

    /**
     * 批量删除
     *
     * @param ids
     */
    void deleteBatch(@NotNull Collection<String> ids) ;

    /****************** 新增 *****************************/
    /**
     * 新增一条数据
     * @param addDTO 新增
     * @return
     */
    T add(@NotNull Object addDTO);

    /****************** 编辑 *****************************/

    /**
     * 编辑数据
     * @param editDTO 编辑
     * @return
     */
    T edit(@NotNull EditPDTO editDTO);

    /**
     * 导出excel
     * @param specPDTO
     * @param outputStream
     */
    void exportExcel(SpecPDTO<T> specPDTO, OutputStream outputStream);

    /**
     * 导入excel
     * @param stream
     */
    void importExcel(InputStream stream);

    /**
     * 保存
     * @param t
     * @return
     */
    T save(@NotNull T t);




    Class<T> getEntityClass();

}
